package com.example.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.RandomUtil;
import com.example.common.enums.ModuleEnum;
import com.example.common.enums.OrderEnum;
import com.example.common.enums.RoleEnum;
import com.example.controller.domain.SearchRequest;
import com.example.entity.*;
import com.example.exception.CustomException;
import com.example.mapper.WorksMapper;
import com.example.utils.TimeUtils;
import com.example.utils.TokenUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 文艺作品业务处理
 **/
@Service
public class WorksService {

    @Resource
    private WorksMapper worksMapper;
    @Resource
    private LikesService likesService;
    @Resource
    private CollectService collectService;
    @Resource
    private ReportService reportService;
    @Resource
    private CommentService commentService;
    @Resource
    private SearchService searchService;

    /**
     * 新增
     */
    public void add(Works works) {
        works.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
        works.setDelTag("0");
        if (worksMapper.insert(works) < 1) {
            throw new CustomException("添加文艺作品失败");
        }
    }

    /**
     * 删除
     */
    public long deleteById(Integer id) {
        return worksMapper.deleteById(id);
    }

    /**
     * 批量删除
     */
    public long deleteBatch(List<Integer> ids) {
        long sum = 0;
        for (Integer id : ids) {
            sum += worksMapper.deleteById(id);
        }
        return sum;
    }

    /**
     * 修改
     */
    public void updateById(Works works) {
        works.setUpdateTime(Timestamp.valueOf(LocalDateTime.now()));
        if (worksMapper.updateById(works) < 1) {
            throw new CustomException("更新文艺作品失败");
        }
    }

    /**
     * 根据ID查询
     */
    public Works selectById(Integer id) {
        Works works = worksMapper.selectById(id);
        works.setReleaseTime(TimeUtils.TimestampToDateFormat(works.getCreateTime()));
        if (Objects.isNull(works.getUpdateTime())) {
            works.setLastUpdateTime(TimeUtils.TimestampToDateFormat(works.getCreateTime()));
        } else {
            works.setLastUpdateTime(TimeUtils.TimestampToDateFormat(works.getUpdateTime()));
        }
        Account currentUser = TokenUtils.getCurrentUser();
        Integer userId = null;
        if (RoleEnum.USER.name().equals(currentUser.getRole())) {
            userId = currentUser.getId();
        }

        List<Collect> collectList = collectService.selectCollect(id, userId, ModuleEnum.WORKS.getValue(), "0");
        works.setUserCollect(CollUtil.isNotEmpty(collectList));

        List<Collect> list = collectService.selectCollect(id, null, ModuleEnum.WORKS.getValue(), "0");
        works.setCollectCount(list.size());

        List<Likes> likesList = likesService.selectLikes(id, userId, ModuleEnum.WORKS.getValue(), "0");
        works.setUserLike(CollUtil.isNotEmpty(likesList));

        List<Likes> allLikesList = likesService.selectLikes(id, null, ModuleEnum.WORKS.getValue(), "0");
        works.setLikesCount(allLikesList.size());

        List<Report> reportList = reportService.selectReport(id, userId, ModuleEnum.WORKS.getValue());
        works.setUserReport(CollUtil.isNotEmpty(reportList));
//        Map<String, Object> mapping = workNotebookMappingMapper.select(new HashMap<String, Object>() {
//            {
//                put("workId", String.valueOf(id));
//            }
//        });
//        if (!ObjectUtils.isEmpty(mapping)) {
//            works.setNotebookId((Integer) mapping.get("notebook_id"));
//        }
        return works;
    }

    /**
     * 查询所有
     */
    public List<Works> selectAll(Works works) {
        Account currentUser = TokenUtils.getCurrentUser();
        if (RoleEnum.USER.name().equals(currentUser.getRole())) {
            works.setUserId(currentUser.getId());
        }
        List<Works> list = worksMapper.selectAll(works);
        list.forEach(entity -> {
            if (Objects.isNull(entity.getUpdateTime())) {
                entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime()));
                entity.setLastUpdateTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime()));
            } else {
                entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime()));
                entity.setLastUpdateTime(TimeUtils.TimestampToDateFormat(entity.getUpdateTime()));
            }
        });
        return list;
    }

    /**
     * 分页查询
     */
    public PageInfo<Works> selectPage(Works works, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Works> list = worksMapper.selectAll(works);
        list.forEach(entity -> {
            if (Objects.isNull(entity.getUpdateTime())) {
                entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime()));
                entity.setLastUpdateTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime()));
            } else {
                entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime()));
                entity.setLastUpdateTime(TimeUtils.TimestampToDateFormat(entity.getUpdateTime()));
            }
        });
        return PageInfo.of(list);
    }

    public PageInfo<Works> queryForMyWorks(Works works, Integer pageNum, Integer pageSize) {
        works.setUserId(TokenUtils.getCurrentUser().getId());
        PageHelper.startPage(pageNum, pageSize);
        List<Works> list=worksMapper.queryForMyWorks(works);
        list.forEach(entity -> {
            if (Objects.isNull(entity.getUpdateTime())) {
                entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime()));
                entity.setLastUpdateTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime()));
            } else {
                entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime()));
                entity.setLastUpdateTime(TimeUtils.TimestampToDateFormat(entity.getUpdateTime()));
            }
        });
        return PageInfo.of(list);
    }

    /**
     * 随机推荐
     */
    public List<Works> selectRecommend() {
        List<Works> worksList = worksMapper.selectTop10();
        worksList.forEach(entity -> entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime())));
        if (worksList.size() <= 4) {
            return worksList;
        }
        List<Works> works = new ArrayList<>();
        Set<Integer> nums = new HashSet<>();
        while (nums.size() < 4) {
            int num = RandomUtil.randomInt(0, worksList.size() - 1); // 随机找到一个序号 这个序号就是 worksList 其中一个元素的序号
            if (!nums.contains(num)) {
                nums.add(num);
                Works w = worksList.get(num);
                works.add(w);
            }
        }
        return works;
    }

    public long updateCount(Integer id) {
        return worksMapper.updateCount(id);
    }

    public PageInfo<Works> selectCollect(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        Integer userId = null;
        // 如果是普通用户 那么只查询自己的文艺作品
        Account currentUser = TokenUtils.getCurrentUser();
        if (RoleEnum.USER.name().equals(currentUser.getRole())) {
            userId = currentUser.getId();
        }
        List<Works> list = worksMapper.selectCollect(userId);
        list.forEach(entity -> entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime())));
        return PageInfo.of(list);
    }

    // 统计最近7天每天发布的菜谱的数量
    public List<Dict> selectCount() {
        List<Works> worksList = worksMapper.selectAll(null);  // 查出所有的文艺作品
        worksList.forEach(works -> works.setReleaseTime(TimeUtils.TimestampToDateFormat(works.getCreateTime())));
        // 先查最近一周的日期
        Date today = new Date();
        DateTime yesterday = DateUtil.offsetDay(today, -1);
        DateTime date = DateUtil.offsetDay(today, -7);
        List<DateTime> dateTimeList = DateUtil.rangeToList(date, yesterday, DateField.DAY_OF_YEAR);
        List<String> dateList = dateTimeList.stream().map(DateUtil::formatDate).collect(Collectors.toList());  //  2024-01-10
        List<Dict> dictList = new ArrayList<>();
        for (String dateStr : dateList) {  // 2024-01-10
            long count = worksList.stream().filter(works -> works.getReleaseTime().contains(dateStr)).count();
            Dict dict = Dict.create().set("date", dateStr.substring(5)).set("count", count);
            dictList.add(dict);
        }
        return dictList;
    }

    public List<Dict> selectCategoryCount() {
        List<Works> worksList = worksMapper.selectAll(null);
        Set<String> categorySet = worksList.stream().map(Works::getCategory).collect(Collectors.toSet());
        List<Dict> dictList = new ArrayList<>();
        for (String category : categorySet) {
            long count = worksList.stream().filter(works -> works.getCategory().equals(category)).count();
            Dict dict = Dict.create().set("name", category).set("value", count);
            dictList.add(dict);
        }
        return dictList;
    }

    public PageInfo<Works> queryForListBySearchKeyword(SearchRequest searchRequest, Integer pageNum, Integer pageSize) {
        if(!Objects.isNull(searchRequest.getSearchKeyword())){
            searchService.search(searchRequest,"文艺作品");
        }
        PageHelper.startPage(pageNum, pageSize);
        List<Works> list;
        if (searchRequest.getOrderType().equals(OrderEnum.COUNT.getValue())) {
            PageHelper.orderBy("works.count desc");
            list = worksMapper.queryForListBySearchKeyword(searchRequest);
        } else if (searchRequest.getOrderType().equals(OrderEnum.POSITIVE.getValue())) {
            PageHelper.orderBy("works.create_time asc");
            list = worksMapper.queryForListBySearchKeyword(searchRequest);
        } else {
            PageHelper.orderBy("works.create_time desc");
            list = worksMapper.queryForListBySearchKeyword(searchRequest);
        }
        list.forEach(entity -> entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime())));
        return PageInfo.of(list);
    }

    public PageInfo<Works> queryForListBySearchKeywordCount(SearchRequest searchRequest, Integer pageNum, Integer pageSize) {
        if(!Objects.isNull(searchRequest.getSearchKeyword())){
            searchService.search(searchRequest,"文艺作品");
        }
        PageHelper.startPage(pageNum, pageSize);
        List<Works> list;
        List<Works> WorksList = worksMapper.queryForListBySearchKeyword(searchRequest);
        List<Likes> likesList = likesService.selectWorksAll();
        List<Collect> collectList = collectService.selectWorksAll();
        List<Comment> commentList = commentService.selectWorksAll();
        for (Works works : WorksList) {
            int likeCount = (int) likesList.stream().filter(p -> p.getFid().equals(works.getId())).count();  // 点赞的个数
            works.setLikesCount(likeCount);
            int collectCount = (int) collectList.stream().filter(p -> p.getFid().equals(works.getId())).count();  // 收藏的个数
            works.setCollectCount(collectCount);
            int commentCount = (int) commentList.stream().filter(p -> p.getFid().equals(works.getId())).count();  // 点赞的个数
            works.setCommentCount(commentCount);
            //  计算热度 如果点赞过了，那么我们就开始计算权重  点赞的权重是2  收藏的权重也是2  浏览的权重是1 评论是3
            works.setHot(likeCount * 2 + collectCount * 2 + commentCount * 3 + works.getCount());
        }
        if (searchRequest.getOrderType().equals(OrderEnum.LIKE.getValue())) {
            list = WorksList.stream().sorted((d1, d2) -> d2.getLikesCount().compareTo(d1.getLikesCount())).collect(Collectors.toList());
        } else if (searchRequest.getOrderType().equals(OrderEnum.COLLECT.getValue())) {
            list = WorksList.stream().sorted((d1, d2) -> d2.getCollectCount().compareTo(d1.getCollectCount())).collect(Collectors.toList());
        } else if (searchRequest.getOrderType().equals(OrderEnum.HOT.getValue())) {
            list = WorksList.stream().sorted((d1, d2) -> d2.getHot().compareTo(d1.getHot())).collect(Collectors.toList());
        } else {
            list = WorksList.stream().sorted((d1, d2) -> d2.getCommentCount().compareTo(d1.getCommentCount())).collect(Collectors.toList());
        }
        list.forEach(entity -> entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime())));
        return PageInfo.of(list);
    }
}
